package com.duck.duckchatbackend.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

import javax.annotation.Resource;

import com.duck.duckchatbackend.entity.config.AppConfig;
import com.duck.duckchatbackend.entity.constans.Constants;
import com.duck.duckchatbackend.entity.enums.AppUpdateFileTypeEnum;
import com.duck.duckchatbackend.entity.enums.AppUpdateSatusEnum;
import com.duck.duckchatbackend.entity.enums.ResponseCodeEnum;
import com.duck.duckchatbackend.exception.BusinessException;
import org.springframework.stereotype.Service;

import com.duck.duckchatbackend.entity.enums.PageSize;
import com.duck.duckchatbackend.entity.query.AppUpdateQuery;
import com.duck.duckchatbackend.entity.po.AppUpdate;
import com.duck.duckchatbackend.entity.vo.PaginationResultVO;
import com.duck.duckchatbackend.entity.query.SimplePage;
import com.duck.duckchatbackend.mappers.AppUpdateMapper;
import com.duck.duckchatbackend.service.AppUpdateService;
import com.duck.duckchatbackend.utils.StringTools;
import org.springframework.web.multipart.MultipartFile;


/**
 * app发布 业务接口实现
 */
@Service("appUpdateService")
public class AppUpdateServiceImpl implements AppUpdateService {

    @Resource
    private AppUpdateMapper<AppUpdate, AppUpdateQuery> appUpdateMapper;
    @Resource
    private AppConfig appConfig;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<AppUpdate> findListByParam(AppUpdateQuery param) {
        return this.appUpdateMapper.selectList(param);
    }

    /**
     * 根据条件查询列表
     */
    @Override
    public Integer findCountByParam(AppUpdateQuery param) {
        return this.appUpdateMapper.selectCount(param);
    }

    /**
     * 分页查询方法
     */
    @Override
    public PaginationResultVO<AppUpdate> findListByPage(AppUpdateQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<AppUpdate> list = this.findListByParam(param);
        PaginationResultVO<AppUpdate> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Integer add(AppUpdate bean) {
        return this.appUpdateMapper.insert(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Integer addBatch(List<AppUpdate> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.appUpdateMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或者修改
     */
    @Override
    public Integer addOrUpdateBatch(List<AppUpdate> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0;
        }
        return this.appUpdateMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Integer updateByParam(AppUpdate bean, AppUpdateQuery param) {
        StringTools.checkParam(param);
        return this.appUpdateMapper.updateByParam(bean, param);
    }

    /**
     * 多条件删除
     */
    @Override
    public Integer deleteByParam(AppUpdateQuery param) {
        StringTools.checkParam(param);
        return this.appUpdateMapper.deleteByParam(param);
    }

    /**
     * 根据Id获取对象
     */
    @Override
    public AppUpdate getAppUpdateById(Integer id) {
        return this.appUpdateMapper.selectById(id);
    }

    /**
     * 根据Id修改
     */
    @Override
    public Integer updateAppUpdateById(AppUpdate bean, Integer id) {
        return this.appUpdateMapper.updateById(bean, id);
    }

    /**
     * 根据ID删除应用更新记录
     * 此方法首先会根据提供的ID查询数据库中的应用更新记录如果记录的状态不是初始化状态，
     * 则抛出业务异常，表明该记录不允许被删除如果记录状态允许删除，则继续执行删除操作
     *
     * @param id 应用更新记录的ID，用于标识要删除的记录
     * @return 返回删除操作影响的行数如果返回1，表示删除成功；如果返回0，表示删除失败
     * @throws BusinessException 当应用更新记录的状态不是初始化状态时，抛出此异常
     */
    @Override
    public Integer deleteAppUpdateById(Integer id) {
        // 根据ID查询应用更新记录
        AppUpdate dbInfo = this.getAppUpdateById(id);
        // 检查应用更新记录的状态是否为初始化状态
        if (!AppUpdateSatusEnum.INIT.getStatus().equals(dbInfo.getStatus())) {
            // 如果状态不是初始化状态，抛出业务异常
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        // 执行删除操作，并返回删除结果
        return this.appUpdateMapper.deleteById(id);
    }

    /**
     * 根据Version获取对象
     */
    @Override
    public AppUpdate getAppUpdateByVersion(String version) {
        return this.appUpdateMapper.selectByVersion(version);
    }

    /**
     * 根据Version修改
     */
    @Override
    public Integer updateAppUpdateByVersion(AppUpdate bean, String version) {
        return this.appUpdateMapper.updateByVersion(bean, version);
    }

    /**
     * 根据Version删除
     */
    @Override
    public Integer deleteAppUpdateByVersion(String version) {
        return this.appUpdateMapper.deleteByVersion(version);
    }

    @Override
    public void saveUpdate(AppUpdate appUpdate, MultipartFile file) throws IOException {

        AppUpdateFileTypeEnum fileTypeEnum = AppUpdateFileTypeEnum.getByType(appUpdate.getFileType());
        if (null == fileTypeEnum) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        if (appUpdate.getId() != null) {
            AppUpdate dbInfo = this.getAppUpdateById(appUpdate.getId());
            if (!AppUpdateSatusEnum.INIT.getStatus().equals(dbInfo.getStatus())) {
                throw new BusinessException(ResponseCodeEnum.CODE_600);
            }
        }


        AppUpdateQuery updateQuery = new AppUpdateQuery();
        updateQuery.setOrderBy("id desc");
        updateQuery.setSimplePage(new SimplePage(0, 1));
        List<AppUpdate> appUpdateList = appUpdateMapper.selectList(updateQuery);


        if (!appUpdateList.isEmpty()) {
            AppUpdate lastest = appUpdateList.get(0);
            Long dbVersion = Long.parseLong(lastest.getVersion().replace(".", ""));
            Long currentVersion = Long.parseLong(appUpdate.getVersion().replace(".", ""));
            if (appUpdate.getId() == null && currentVersion <= dbVersion) {
                throw new BusinessException("新增版本必须大于历史最新版本");
            }
            if (appUpdate.getId() != null && currentVersion >= dbVersion && !appUpdate.getId().equals(lastest.getId())) {
                throw new BusinessException("非最新版本修改时，修改必须小于最新版本号");
            }
            AppUpdate versionDb = appUpdateMapper.selectByVersion(appUpdate.getVersion());
            if (appUpdate.getId() != null && versionDb != null && !versionDb.getId().equals(appUpdate.getId())) {
                throw new BusinessException("版本号已存在");
            }
        }
        if (appUpdate.getId() == null) {
            appUpdate.setCreateTime(new Date());
            appUpdate.setStatus(AppUpdateSatusEnum.INIT.getStatus());
            appUpdateMapper.insert(appUpdate);
        } else {
            appUpdateMapper.updateById(appUpdate, appUpdate.getId());
        }

        if (file != null) {
            File folder = new File(appConfig.getProjectFolder() + Constants.APP_UPDATE_FOLDER);
            if (!folder.exists()) {
                folder.mkdirs();
            }
            file.transferTo(new File(folder.getAbsolutePath() + "/" + appUpdate.getId() + Constants.APP_EXE_SUFFIX));
        }
    }
    /**
     * 更新应用版本状态
     *
     * @param id 应用版本的唯一标识符
     * @param status 新的应用版本状态标识符
     * @param grayscaleUid 灰度发布UID，用于标识灰度发布的版本
     *
     * 此方法用于更新特定应用版本的状态，以及在灰度发布的情况下更新灰度UID
     * 它首先验证给定的状态是否有效，然后根据状态和灰度UID执行相应的更新操作
     */
    @Override
    public void postUpdate(Integer id, Integer status,String grayscaleUid) {
        // 根据给定的状态标识符获取应用版本状态枚举
        AppUpdateSatusEnum statusEnum = AppUpdateSatusEnum.getByStatus(status);
        // 如果状态无效，抛出业务异常
        if(null == statusEnum){
            throw  new BusinessException(ResponseCodeEnum.CODE_600);
        }
        // 如果状态为灰度发布且灰度UID为空，抛出业务异常
        if(AppUpdateSatusEnum.GRAYSCALE == statusEnum && StringTools.isEmpty(grayscaleUid)){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        // 如果状态不是灰度发布，将灰度UID设置为空字符串
        if(AppUpdateSatusEnum.GRAYSCALE!= statusEnum){
            grayscaleUid = "";
        }
        // 创建一个AppUpdate对象并设置其状态和灰度UID
        AppUpdate update = new AppUpdate();
        update.setStatus(status);
        update.setGrayscaleUid(grayscaleUid);
        // 使用应用版本的唯一标识符执行更新操作
        appUpdateMapper.updateById(update,id);
    }
    @Override
    public AppUpdate getLatestUpdate(String appVersion, String uid) {
        return appUpdateMapper.selectLatestUpdate(appVersion,uid);

    }
}